<?php

class PaymentController extends Controller
{

    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
            array(
                'application.filters.RequireLoginFilter',
            ),
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'users' => array('@'),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    public function actionIndex()
    {
        outputJsByList(Customers::model()->getActiveList(), 'customerList');
        outputJsByList(PaymentMethods::getList(), 'paymentMethodList');
        outputJsByList(SalesDepartments::getListData(), 'deptList');
        outputJsByList(Jobs::getList(), 'jobList');
        outputJsByList(Coa::model()->getListWithDesc(), 'accountsList');
        //outputJsByList(RecLed::model()->getPaymentTypeList(), 'paymentTypeList');
        $this->render('index', array(
            'rec' => new Rec(),
            'recleg' => new RecLed
        ));
    }

    public function actionApplyCreditPayment()
    {
        //get invoice data
        //get all recled 
        //calculate applied payment ( <= invoice amount - paid)
        //if total applied > invoice remain amount , return
        //update remain amount to rec
        //write to ledger
        //write to recapply
        //write to finledger

        if (isset($_POST['payment']) && isset($_POST['invoice']))
        {
            $rec = Rec::model()->find('invoice=:invoice', array(
                        'invoice' => $_POST['invoice']
                   ));
            $invModel       = Invoice::model()->findByPk($_POST['invoice']);
            $totalApplied   = 0;
            /* @var $rec Rec */
            if ($rec != NULL)
            {
                //get total
                foreach ($_POST['payment'] as $i => $item)
                {
                    $recled = RecLed::model()->findByPk($item['entryid']);
                    if ($recled != NULL)
                    {
                        if ($item['appliedamount'] > $recled->amount)
                        {
                            $item['appliedamount'] = $recled->amount;
                        }
                        $totalApplied+=$item['appliedamount'];
                    }
                    else
                    {
                        $this->showAjaxMessage('Entry can not be found');
                    }
                }
                //we got the total applied now compare it with the invoice amount
                if ($totalApplied > ($rec->invamt - $rec->paid))
                {
                    $this->showAjaxMessage('Excess invoice amount');
                }

                //it's fine, now save all to db
                //save to each
                foreach ($_POST['payment'] as $item)
                {
                    $recled = RecLed::model()->findByPk($item['entryid']);
                    /* @var $recled RecLed */
                    if ($item['appliedamount'] > $recled->amount)
                    {
                        $item['appliedamount'] = $recled->amount;
                    }
                    $recled->amount-=$item['appliedamount'];
                    $masterRecled   = RecLed::model()->findByPk($recled->appliedfromid);
                    /* @var $masterRecled RecLed */
                    $masterRecled->remaincredit-=$item['appliedamount'];

                    $recledApply    = new RecLedApply;
                    $recledApply->custno        = $rec->custno;
                    $recledApply->locno         = $rec->locno;
                    $recledApply->ledgerentryid = $recled->entryid;
                    $recledApply->paid          = $item['appliedamount'];


                    $recledApply->applieddate   = date('Y-m-d');
                    $recledApply->type          = RecLed::TYPE_NORMAL;
                    $recledApply->number        = $rec->invoice;

                    $log1               = new Xlogrec;
                    $log1->id           = createRandomUUID();
                    $log1->transdate    = date('Y-m-d');
                    $log1->entryid      = $recled->entryid;
                    $log1->invoice      = $recled->invoice;
                    $log1->amount       = $item['appliedamount'];
                    $log1->memo         = 'RecRecordPayment: Added line to receivables journal entry';
                    $log1->counter      = 0;
                    $log1->custno       = $recled->custno;

                    $log2               = new Xlogrec;
                    $log2->id           = createRandomUUID();
                    $log2->transdate    = date('Y-m-d');
                    $log2->entryid      = $recled->entryid;
                    $log2->invoice      = $recled->invoice;
                    $log2->amount       = -$item['appliedamount'];
                    $log2->memo         = 'RecRecordPayment: Recorded payment record in RecLed';
                    $log2->counter      = 1;
                    $log2->custno       = $recled->custno;
                    if ($recled->validate() && $masterRecled->validate()
                            && $recledApply->validate()
                            && $log1->validate()
                            && $log2->validate())
                    {
                        if (!($recled->save()
                                && $masterRecled->save()
                                && $recledApply->save()
                                && $log1->save()
                                && $log2->save()))
                        {
                            echo json_encode(array(
                                'success'   => false,
                                'msg'       => 'Error apply payment'
                            ));
                            return;
                        }
                    }
                    else
                    {
                        echo json_encode(array(
                            'success'   => false,
                            'msg'       => 'Error saving data'
                        ));
                        return;
                    }

                    $rec->paid+=$item['appliedamount'];
                    //update remain amount
                }
                $rec->save();
            }
            else
            {
                $this->showAjaxMessage('Invalid data');
            }
        }
        $this->showAjaxMessage('Save successful', true);
    }
    public function actionSavePayment(){
        $paymentList  = $_POST['payment'];
        $paymentUtil= new PaymentUtil();
        $result = $paymentUtil->savePayment($paymentList,$_POST['paymentamount'],$_POST['paymethod'],$_POST['ckno'],$_POST['memo'],$_POST['date']);
        if($result){
            $this->showAjaxMessage('Save successful',true);
        }else{
            $this->showAjaxMessage('Error saving data',false);
        }
        
    }
    

    public function actionGetSalesOrderList($custno, $locno=null, $page=0, $sort=NULL)
    {
        $data= $this->getInvoiceAndSalesOrderList($custno, Invoice::TYPE_SALES_ORDERS, $locno, $page, $sort);
        echo json_encode($data);
    }
    public function actionGetAllInvoiceAndSalesOrderList($page=0, $sort=NULL){
        $data=$this->getInvoiceAndSalesOrderList(null, null, null, $page, $sort);
        echo json_encode($data);
    }
    protected function getInvoiceAndSalesOrderList($custno=null,$invoiceType=null,$locno=null,$page=0,$sort=null){
        assert('$invoiceType==null || ($invoiceType == Invoice::TYPE_INVOICE || $invoiceType== Invoice::TYPE_SALES_ORDERS)');
        if ($page > 0)
            $page--;

        $criteria = new CDbCriteria();
        $criteria->alias = 'i';
        $criteria->compare('i.custno', $custno);
        if ($locno != 'null' && $locno != null)
        {
            $criteria->compare('i.locno', $locno);
        } 
        
        $criteria->join = 'left join tbl_rec r on r.invoice=i.invoice';        
        
        $criteria->addCondition('
            (i.invoicetype=:typeInvoice or i.invoicetype = :typeSalesOrder)
            AND
            ((i.invoicetype=:typeInvoice AND r.paid !=r.invamt and  i.amountcharge>0) 
            OR
            (i.amountcharge >0 AND i.invoicetype=:typeSalesOrder))');
        $criteria->params['typeInvoice']=Invoice::TYPE_INVOICE;
        $criteria->params['typeSalesOrder']=Invoice::TYPE_SALES_ORDERS;
        if ($sort != NULL)
        {
            $order = CJSON::decode($sort);
            $criteria->order = isset($order) ? $order[0]['property'] . ' ' . $order[0]['direction'] : NULL;
        }
        else
        {
            $criteria->order = 'CAST( SUBSTR( i.invoice, 1,LOCATE(  "-", i.invoice )-1  ) AS SIGNED) DESC ,CAST( SUBSTR( i.invoice, LOCATE(  "-", i.invoice ) +1 ) AS SIGNED ) DESC';
        }
        $pages = new CActiveDataProvider('Invoice', array(
                    'criteria' => $criteria,
                    'pagination' => array(
                        'pageSize' => 999999,
                        'currentPage' => $page
                    )
                ));
        $rs = array();
        if (count($pages->getData()) > 0)
        {
            $rs['totalCount'] = $pages->getTotalItemCount();
            foreach ($pages->getData() as $i => $item)
            {
                /* @var $item Invoice */
                $rs['data'][] = $item->getAttributes();
                $rs['data'][$i]['paid'] = $item->getPaymentApplied();
                $rs['data'][$i]['amountdue'] = $item->amountcharge - $rs['data'][$i]['paid'];
                if ($rs['data'][$i]['amountdue'] < 0)
                {
                    $rs['data'][$i]['amountdue'] = 0;
                }
                $rs['data'][$i]['location'] = $item->location->locname;
                $rs['data'][$i]['tempamountdue'] = $rs['data'][$i]['amountdue'];
                $rs['data'][$i]['departmenttext'] = SalesDepartments::getText($item->department);
                $rs['data'][$i]['temppaid'] = $rs['data'][$i]['paid'];
            }

            return $rs;
        }
    }
    public function actionGetList($custno, $locno=null, $page=0, $sort=NULL)
    {
        $data= $this->getInvoiceAndSalesOrderList($custno, Invoice::TYPE_INVOICE, $locno, $page, $sort);
        echo json_encode($data);
    }

    public function actionCreditPrepaymentList($type, $custno, $locno=NULL, $page=0, $sort=NULL)
    {
        if ($page > 0)
            $page--;
        if (empty($custno) || empty($type))
        {
            return;
        }
        $crit = new CDbCriteria();
        $crit->compare('type', $type, false);
        $crit->compare('amount', ">0");
        $crit->compare('custno', $custno, false, 'and');

        if ($locno != NULL)
        {
            $crit->compare('locno', $locno);
        }

        $order = CJSON::decode($sort);
        if ($sort != NULL)
        {
            $crit->order = $order[0]['property'] . ' ' . $order[0]['direction'];
        }

        $data = new CActiveDataProvider('RecLed', array(
                    'criteria' => $crit
                ));
        $rs = array();
        if (count($data->getData()) > 0)
        {
            foreach ($data->getData() as $i => $item)
            {
                $rs['data'][] = $item->getAttributes();
                $rs['data'][$i]['paymethodtext'] = PaymentMethods::getDesc($item->paymethod);
            }
            $rs['totalCount'] = $data->getTotalItemCount();
        }
        echo CJSON::encode($rs);
    }

    public function actionGetCustomerCredit($custno)
    {
        $data = Yii::app()->db->createCommand('select sum(amount) from tbl_rec_led where type=:type and custno=:custno')->bindValues(array(
                    'type' => 'c',
                    'custno' => $custno
                ))->queryScalar();
        if ($data !== false)
        {
            echo $data;
        }
        echo 0;
    }

    public function actionGetCustomerPrepayment($custno)
    {
        $data = Yii::app()->db->createCommand('select sum(amount) from tbl_rec_led where type=:type and custno=:custno')->bindValues(array(
                    'type' => 'p',
                    'custno' => $custno
                ))->queryScalar();
        if ($data !== false)
        {
            echo $data;
        }
        echo 0;
    }
    public function actionGetPaymentCenterList($page,$sort=null){
        if($page>0){
            $page--;
        }
        $criteria=new CDbCriteria();
        if($sort!=null){
            $sortData=json_decode($sort);
            $criteria->order=$sort[0]['property'].' '.$sort[0]['direction'];
        }
        $data=new CActiveDataProvider('RecLed',array(
            'criteria'=>$criteria,
            'pagination'=>array(
                'pageSize'=>20,
                'currentPage'=>$page
            )
        ));
        $rs['totalCount']=$data->getTotalItemCount();
        foreach($data->getData() as $i=>$item){
            $rs['data'][$i]=$item->attributes;
            $rs['data'][$i]['typeText']=$item->getPaymentTypeText();
            $rs['data'][$i]['unapplied']=$item->getUnapplied();
        }
        echo json_encode($rs);
    }
    public function actionPaymentCenter(){
        $this->render('paymentCenter');
    }
    public function actionPaymentDetail($id){
        $model=RecLed::model()->findByPk($id);
        if($model!=null){
            $this->render('paymentDetail',array('model'=>$model));
        }else{
            throw new CHttpException('Your requested page can not be found');
        }
    }

}